package com.axzhengxin.platform.business.service.impl;

import com.axzhengxin.platform.afterloan.domain.FspCorInf;
import com.axzhengxin.platform.afterloan.mapper.FspCorInfMapper;
import com.axzhengxin.platform.business.domain.*;
import com.axzhengxin.platform.business.mapper.*;
import com.axzhengxin.platform.business.service.IBizApplyInfoService;
import com.axzhengxin.platform.common.service.IDbExecService;
import com.axzhengxin.platform.common.util.RedisUtil;
import com.axzhengxin.platform.statistics.domain.ProvinceStatistics;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysDeptMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 客户需求Service业务层处理
 *
 * @author axzhengxin
 * @date 2021-02-20
 */
@Slf4j
@Service
public class BizApplyInfoServiceImpl implements IBizApplyInfoService {
    @Autowired
    private BizApplyInfoMapper bizApplyInfoMapper;

    @Autowired
    private BizFlowInfoMapper bizFlowInfoMapper;

    @Autowired
    private BizFlowTaskMapper bizFlowTaskMapper;

    @Autowired
    private FspCorInfBusinessMapper fspCorInfBusinessMapper;

    @Autowired
    private IDbExecService dbExecService;

    @Autowired
    private BizApproveInfoMapper bizApproveInfoMapper;

    @Autowired
    private BizLoanInfoMapper bizLoanInfoMapper;

    @Autowired
    private BizRepaymentInfoMapper repaymentInfoMapper;

    @Autowired
    private FspCorInfMapper fspCorInfMapper;

    @Autowired
    private BizApplyWarrantRelativeMapper bizApplyWarrantRelativeMapper;

    @Autowired
    private BizPledgeInfoMapper bizPledgeInfoMapper;

    @Autowired
    private BizApplyGuaranteePledgeRelativeMapper bizApplyGuaranteePledgeRelativeMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SysDeptMapper deptMapper;

    /**
     * 查询客户需求
     *
     * @param reqId 客户需求ID
     * @return 客户需求
     */
    @Override
    public BizApplyInfo selectBizApplyInfoById(String reqId) {
        return bizApplyInfoMapper.selectBizApplyInfoById(reqId);
    }

    /**
     * 查询客户需求列表
     *
     * @param bizApplyInfo 客户需求
     * @return 客户需求
     */
    @Override
    @DataScope(deptAlias = "t")
    public List<BizApplyInfo> selectBizApplyInfoList(BizApplyInfo bizApplyInfo) {
        return bizApplyInfoMapper.selectBizApplyInfoList(bizApplyInfo);
    }

    /**
     * 新增客户需求
     *
     * @param bizApplyInfo 客户需求
     * @return 结果
     */
    @Override
    public int insertBizApplyInfo(BizApplyInfo bizApplyInfo) {
        bizApplyInfo.setCreateTime(DateUtils.getNowDate());
        return bizApplyInfoMapper.insertBizApplyInfo(bizApplyInfo);
    }

    /**
     * 修改客户需求
     *
     * @param bizApplyInfo 客户需求
     * @return 结果
     */
    @Override
    public int updateBizApplyInfo(BizApplyInfo bizApplyInfo) {
        bizApplyInfo.setUpdateTime(DateUtils.getNowDate());
        return bizApplyInfoMapper.updateBizApplyInfo(bizApplyInfo);
    }

    /**
     * 批量删除客户需求
     *
     * @param reqIds 需要删除的客户需求ID
     * @return 结果
     */
    @Override
    public int deleteBizApplyInfoByIds(String[] reqIds) {
        return bizApplyInfoMapper.deleteBizApplyInfoByIds(reqIds);
    }

    /**
     * 删除客户需求信息
     *
     * @param reqId 客户需求ID
     * @return 结果
     */
    @Override
    public int deleteBizApplyInfoById(String reqId) {
        return bizApplyInfoMapper.deleteBizApplyInfoById(reqId);
    }


    @Transactional(isolation = Isolation.REPEATABLE_READ,
            rollbackFor = Throwable.class)
    @Override
    public int checkIn(String reqId) {
        try {
            if (redisUtil.getLock(reqId)) {
                int updateRowCount = 0;
                SysUser user = SecurityUtils.getLoginUser().getUser();
                Long deptId = user.getDeptId();
                Long userId = user.getUserId();
                log.debug("尝试对编号为[{}]的需求进行抢单机构数加一", reqId);
                BizApplyInfo bizApplyInfo = bizApplyInfoMapper.selectBizApplyInfoById(reqId);
                SysDept sysDept = deptMapper.selectDeptById(deptId);
                String ancestors = sysDept.getAncestors();
                List<String> ancestorsList = Arrays.asList(ancestors.split(","));
                List<String> list = new ArrayList<>();
                for (int i = 1; i < ancestorsList.size(); i++) {
                    list.add(ancestorsList.get(i));
                }
                list.add(String.valueOf(deptId));
                Map<String, Object> map = new HashMap<>();
                map.put("reqId", reqId);
                map.put("list", list);
                int existFlowInfo = bizApplyInfoMapper.checkExistFlowInfo(map);
                if (existFlowInfo > 0) {
                    return 100;
                }
                Integer checkedCount = bizApplyInfo.getCheckedCount();
                if (checkedCount > 2) {
                    //103
                    return 103;
                }
                updateRowCount = bizApplyInfoMapper.increaseCheckCount(reqId);
                log.debug("影响的需求记录行数[{}]", updateRowCount);

                BizFlowInfo bizFlowInfo = new BizFlowInfo();
                bizFlowInfo.setCreateBy(String.valueOf(userId));
                //10-待分配 1010-待处理 2000-已完成    3000-已拒绝
                bizFlowInfo.setStatus(10);
                /*bizFlowInfo.setCreateTime(new Date());*/
                bizFlowInfo.setCurrentNodeUserId(String.valueOf(userId));
                bizFlowInfo.setBizType("APPLY");
                //指定对应需求记录
                bizFlowInfo.setBizId(reqId);
                bizFlowInfo.setFinanceId(user.getDept().getFinanceId());
                bizFlowInfo.setCurrentNodeDeptId(String.valueOf(deptId));
                bizFlowInfoMapper.insertBizFlowInfo(bizFlowInfo);
                /*
                 * 生成抢单流程流水起点
                 */
                BizFlowTask bizFlowTask = new BizFlowTask();
                bizFlowTask.setFlowUid(bizFlowInfo.getFlowUid());
                bizFlowTask.setUserId(String.valueOf(userId));
                bizFlowTask.setCreateBy(user.getUserId().toString());
                /*bizFlowTask.setCreateTime(new Date());*/
                bizFlowTask.setBizType("APPLY");
                bizFlowTaskMapper.insertBizFlowTask(bizFlowTask);
            } else {
                //110
                return 110;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //释放锁
            redisUtil.disableLock(reqId);
        }
        //200
        return 200;
    }

    /**
     * 查询全部
     *
     * @param bizApplyInfo 需求对象
     * @return list集合
     */
    @Override
    public List<BizApplyInfo> selectApplyInfoList(BizApplyInfo bizApplyInfo) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        //添加一个Flag便于前端判断是否可以进行抢单了
        //1.抢单机构=3      2.是否是放款完成的订单-暂不查询   3.是否当前登录人或当前登录人所属部门已经抢过了  4.当前登录人是否是管理员
        List<BizApplyInfo> bizApplyInfos;
        if (SecurityUtils.isAdmin(user.getUserId())) {
            bizApplyInfos = bizApplyInfoMapper.selectApplyInfoListAdmin(bizApplyInfo);
        } else {
            bizApplyInfos = bizApplyInfoMapper.selectApplyInfoList(bizApplyInfo);
        }
        bizApplyInfos.stream().
                forEach(bizApplyInfo1 -> {
                    boolean flag = true;
                    Integer checkedCount = bizApplyInfo1.getCheckedCount();
                    String bizId = bizApplyInfo1.getBizId();
                    if (checkedCount > 2 || StringUtils.isNotBlank(bizId)) {
                        flag = false;
                    }
                    bizApplyInfo1.setCheckInFlag(flag);
                    String pciBelongNo = bizApplyInfo1.getPciBelongNo();
                    if (StringUtils.isNotBlank(pciBelongNo)) {
                        bizApplyInfo1.setPciBelongType(DictUtils.getDictLabel("biz_industry_type", pciBelongNo));
                    }
                    String customerAreaNo = bizApplyInfo1.getCustomerAreaNo();
                    if (StringUtils.isNotBlank(customerAreaNo)) {
                        bizApplyInfo1.setCustomerArea(DictUtils.getDictLabel("area_codes", customerAreaNo));
                    }
                });
        return bizApplyInfos;
    }

    @Override
    @DataScope(deptAlias = "sd",userAlias = "uu")
    public List<BizApplyInfo> selectAuditingList(BizApplyInfo bizApplyInfo) {
        List<BizApplyInfo> bizApplyInfos = bizApplyInfoMapper.selectAuditingList(bizApplyInfo);
        bizApplyInfos = buildBizApplyList(bizApplyInfos);
        return bizApplyInfos;
    }


    /**
     * 查询订单详情 ——》用户详情、放款信息、授信详情、担保详情、抵押详情、还款信息
     *
     * @param searchApply
     * @return
     */
    @Override
    @DataScope(deptAlias = "ud",userAlias = "ud")
    public BizApplyInfo getBizApplyInfo(BizApplyInfo searchApply) {
        String reqId = searchApply.getReqId();
        BizApplyInfo bizApplyInfo = bizApplyInfoMapper.selectBizApplyInfoById(reqId);
        String customerId = bizApplyInfo.getCustomerId();
        String customerName = bizApplyInfo.getCustomerName();
        String pciBelongNo = bizApplyInfo.getPciBelongNo();
        String bizIndustryType="";
        if (StringUtils.isNotBlank(pciBelongNo)) {
            bizIndustryType = DictUtils.getDictLabel("biz_industry_type", pciBelongNo);

        }
        if (StringUtils.isNotBlank(customerId)) {
            FspCorInf fspCorInf = fspCorInfMapper.selectFspCorInfByCustomerId(customerId);
            fspCorInf.setIndustry(bizIndustryType);
            if (null != fspCorInf) {
                try {
                    dbExecService.getJbxxByEntName(customerName)
                            .ifPresent(result -> {
                                fspCorInf.setEconat(result.getString("ECONAT"));
                                fspCorInf.setEntState(result.getString("STATE"));
                                fspCorInf.setOpScope(result.getString("OPSCOPE"));
                                fspCorInf.setEntTypeName(result.getString("ENTTYPENAME"));
                                try {
                                    fspCorInf.setEstDate(DateUtils.parseDate(result.getString("ESTDATE"), "yyyy-MM-dd HH:mm:ss"));
                                    fspCorInf.setApprDate(DateUtils.parseDate(result.getString("APPRDATE"), "yyyy-MM-dd HH:mm:ss"));
                                } catch (ParseException e) {
                                    log.error("解析日期字符串发生异常", e);
                                }
                            });
                } catch (Exception e) {
                    log.error("远程接口调用发生异常", e);
                    e.printStackTrace();
                }
                bizApplyInfo.setFspCorInf(fspCorInf);
            }
        }
        List<BizApproveInfo> bizApproveInfoList = bizApproveInfoMapper.selectBizApproveInfoByReqId(searchApply);
        //方便前端取值
        List<BizApproveDetail> details = new ArrayList<>();
        if (bizApproveInfoList != null && bizApproveInfoList.size() > 0) {
            for (BizApproveInfo bizApproveInfo : bizApproveInfoList) {
                List<BizApproveDetail> detailList = bizApproveInfo.getDetailList();
                if (detailList != null && detailList.size() > 0) {
                    details.addAll(detailList);
                }
            }
        }
        //放款
        List<BizLoanInfo> bizLoanInfoList = bizLoanInfoMapper.selectBizLoanInfoByReqId(searchApply);
        if (bizLoanInfoList != null && bizLoanInfoList.size() > 0) {
            for (BizLoanInfo bizLoanInfo : bizLoanInfoList) {
                bizLoanInfo.setGuaranteeTypeName(DictUtils.getDictLabel("guarantee_type", bizLoanInfo.getGuaranteeType()));
            }
        }
        //还款
        List<BizRepaymentInfo> bizRepaymentInfoList = repaymentInfoMapper.selectBizRepaymentInfoByReqId(searchApply);
        //担保
        List<BizApplyWarrantRelative> bizApplyWarrantRelativeList =
                bizApplyWarrantRelativeMapper.selectBizApplyWarrantRelativeByReqId(searchApply);
        //抵押业务信息
        List<BizPledgeInfo> bizPledgeInfoList =
                bizPledgeInfoMapper.selectBizPledgeInfoListByReqId(searchApply);
        bizApplyInfo.setBizPledgeInfoList(bizPledgeInfoList);
        bizApplyInfo.setBizApplyWarrantRelativeList(bizApplyWarrantRelativeList);
        bizApplyInfo.setBizRepaymentInfoList(bizRepaymentInfoList);
        bizApplyInfo.setBizLoanInfoList(bizLoanInfoList);
        bizApplyInfo.setBizApproveInfoList(bizApproveInfoList);
        bizApplyInfo.setDetailList(details);
        return bizApplyInfo;
    }


    @Override
    @DataScope(deptAlias = "biz_flow",userAlias = "su")
    public List<BizApplyInfo> selectApproveList(BizApplyInfo bizApplyInfo) {
        List<BizApplyInfo> bizApplyInfos = bizApplyInfoMapper.selectApproveList(bizApplyInfo);
        bizApplyInfos = buildBizApplyList(bizApplyInfos);
        return bizApplyInfos;
    }

    @Override
    @DataScope(deptAlias = "sd",userAlias = "uu")
    public List<BizApplyInfo> loanList(BizApplyInfo applyInfo) {
        List<BizApplyInfo> bizApplyInfos = bizApplyInfoMapper.loanList(applyInfo);
        bizApplyInfos = buildBizApplyList(bizApplyInfos);
        return bizApplyInfos;
    }

    @Override
    @DataScope(deptAlias = "biz_flow",userAlias = "biz_flow")
    public List<BizApplyInfo> guaranteeList(BizApplyInfo applyInfo) {
        List<BizApplyInfo> bizApplyInfos = bizApplyInfoMapper.guaranteeList(applyInfo);
        bizApplyInfos = buildBizApplyList(bizApplyInfos);
        return bizApplyInfos;

    }

    @Override
    public List<ProvinceStatistics> getNumericalStatementByDept(List<BizApplyInfo> list) {
        return bizApplyInfoMapper.selectNumericalStatementByDept(list);
    }

    @Override
    public List<ProvinceStatistics> getNumericalStatementByDeptYearAndMonth(List<BizApplyInfo> list) {
        return bizApplyInfoMapper.selectNumericalStatementByDeptYearAndMonth(list);
    }

    @Override
    public List<BizApplyInfo> getNumericalStatementByArea(List<BizApplyInfo> list) {
        return bizApplyInfoMapper.selectNumericalStatementByArea(list);
    }

    @Override
    public List<ProvinceStatistics> getNumericalStatementByAreaYearAndMonth(List<BizApplyInfo> list) {
        return bizApplyInfoMapper.selectNumericalStatementByAreaYearAndMonth(list);
    }

    @Override
    public List<ProvinceStatistics> getNumericalStatementByCustome(List<BizApplyInfo> list) {
        return bizApplyInfoMapper.selectNumericalStatementByCustome(list);
    }

    @Override
    public BizApplyInfo getApproveInfo(BizApplyInfo searchApply) {
        BizApplyInfo bizApplyInfo = new BizApplyInfo();
        List<BizApproveInfo> bizApproveInfoList = bizApproveInfoMapper.selectBizApproveInfoByReqId(searchApply);
        BigDecimal sumApproveAmount = new BigDecimal(0);
        for (BizApproveInfo bizApproveInfo : bizApproveInfoList) {
            BigDecimal approveAmount = bizApproveInfo.getApproveAmount();
            sumApproveAmount = sumApproveAmount.add(approveAmount);
        }
        ;
        //方便前端取值
        List<BizApproveDetail> details = new ArrayList<>();
        if (bizApproveInfoList != null && bizApproveInfoList.size() > 0) {
            for (BizApproveInfo bizApproveInfo : bizApproveInfoList) {
                List<BizApproveDetail> detailList = bizApproveInfo.getDetailList();
                if (detailList != null && detailList.size() > 0) {
                    details.addAll(detailList);
                }
            }
        }
        bizApplyInfo.setSumApproveAmount(sumApproveAmount.setScale(2, RoundingMode.HALF_UP));
        bizApplyInfo.setBizApproveInfoList(bizApproveInfoList);
        bizApplyInfo.setDetailList(details);
        return bizApplyInfo;
    }

    @Override
    @DataScope(deptAlias = "biz_flow",userAlias = "biz_flow")
    public List<BizApplyInfo> pledgeList(BizApplyInfo applyInfo) {
        List<BizApplyInfo> bizApplyInfos = bizApplyInfoMapper.pledgeList(applyInfo);
        bizApplyInfos = buildBizApplyList(bizApplyInfos);
        return bizApplyInfos;
    }

    /**
     * 撤销
     * 修改last_flag,新增task，flowInfo
     *
     * @param reqId
     * @return
     */
    @Override
    public AjaxResult backApply(String reqId) {
        List<BizFlowInfoVo> bizFlowInfoVos = bizApplyInfoMapper.getFlowUidAndTaskId(reqId);
        try {
            if (bizFlowInfoVos != null && bizFlowInfoVos.size() > 0) {
                bizFlowInfoVos.stream().forEach(bizFlowInfoVo -> {
                    BizFlowInfo bizFlowInfo = bizFlowInfoMapper.selectBizFlowInfoByFlowUid(bizFlowInfoVo.getFlowUid());
                    bizFlowInfoMapper.updateByFlowUid(bizFlowInfoVo.getFlowUid(), "4000");
                    //新增流程TASK
                    BizFlowTask bizFlowTask = new BizFlowTask();
                    bizFlowTask.setStatus(4000);
                    bizFlowTask.setBizType(bizFlowInfo.getBizType());
                    bizFlowTask.setFlowUid(bizFlowInfo.getFlowUid());
                    bizFlowTask.setUserId(bizFlowInfo.getCurrentNodeUserId());
                    bizFlowTaskMapper.insertBizFlowTask(bizFlowTask);
                });
            }
            bizApplyInfoMapper.updateCancelFlag(reqId);
            return AjaxResult.success("撤销成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.error("撤销失败");
    }

    @Override
    public List<BizApplyInfo> factoringList(BizApplyInfo applyInfo) {
        return bizApplyInfoMapper.factoringList(applyInfo);
    }


    private BizFlowInfo buildFlowInfo(String bizType, Integer status, String bizId, SysUser user) {
        Long userId = user.getUserId();
        BizFlowInfo bizFlowInfo = new BizFlowInfo();
        bizFlowInfo.setBizType(bizType);
        /*bizFlowInfo.setCreateTime(new Date());*/
        bizFlowInfo.setBizId(bizId);
        bizFlowInfo.setFinanceId(user.getDept().getFinanceId());
        bizFlowInfo.setCurrentNodeUserId(String.valueOf(userId));
        bizFlowInfo.setCurrentNodeDeptId(String.valueOf(user.getDeptId()));
        bizFlowInfo.setStatus(status);
        bizFlowInfo.setCreateBy(String.valueOf(userId));
        return bizFlowInfo;
    }

    public BizFlowTask buildFlowTask(String bizType, Integer status, String bizId, SysUser user) {
        Long userId = user.getUserId();

        BizFlowTask bizFlowTask = new BizFlowTask();
        bizFlowTask.setStatus(status);
        /*bizFlowTask.setCreateTime(new Date());*/
        bizFlowTask.setCreateBy(String.valueOf(userId));
        bizFlowTask.setBizId(bizId);
        bizFlowTask.setBizType(bizType);
        bizFlowTask.setUserId(String.valueOf(userId));
        return bizFlowTask;
    }


    public List<BizApplyInfo> buildBizApplyList(List<BizApplyInfo> bizApplyInfos) {
        bizApplyInfos.stream().
                forEach(bizApplyInfo1 -> {
                    BigDecimal approveAmount = bizApplyInfo1.getApproveAmount();
                    if (approveAmount != null) {
                        bizApplyInfo1.setApproveAmount(approveAmount.setScale(2, RoundingMode.HALF_UP));
                    }
                    String pciBelongNo = bizApplyInfo1.getPciBelongNo();
                    if (StringUtils.isNotBlank(pciBelongNo)) {
                        String biz_industry_type = DictUtils.getDictLabel("biz_industry_type", pciBelongNo);
                        if (StringUtils.isNotBlank(biz_industry_type)) {
                            bizApplyInfo1.setPciBelongType(biz_industry_type);
                        }
                    }
                    String customerAreaNo = bizApplyInfo1.getCustomerAreaNo();
                    if (StringUtils.isNotBlank(customerAreaNo)) {
                        String area_codes = DictUtils.getDictLabel("area_codes", customerAreaNo);
                        if (StringUtils.isNotBlank(area_codes)) {
                            bizApplyInfo1.setCustomerArea(area_codes);
                        }
                    }
                });
        return bizApplyInfos;
    }


}
